﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Microsoft.EnterpriseManagement.Common;
using Microsoft.EnterpriseManagement.Configuration;

namespace System.ServiceManager.Facade
{
    public partial class CriteriaBuilder
    {
        public static XNamespace NameSpace = XNamespace.Get("http://Microsoft.EnterpriseManagement.Core.Criteria/");
        readonly List<string> managagementpacks = new List<string>();
        readonly List<string> aliases = new List<string>();

        public CriteriaBuilder()
        {
        }

        public CriteriaBuilder(string nameSpace)
        {
            NameSpace = XNamespace.Get(nameSpace);
        }

        //TODO What about different versions?
        public void AddReferences(string managementPackName, string alias)
        {
            if (string.IsNullOrEmpty(managementPackName))
                throw new ArgumentNullException(managementPackName);
            if (string.IsNullOrEmpty(alias))
                throw new ArgumentNullException(alias);

            managagementpacks.Add(managementPackName);
            aliases.Add(alias);
        }

        public ObjectProjectionCriteria CreateCriteria(ManagementPackTypeProjection typeProjection, CriteriaElement element)
        {
            var root = GetRoot();
            root.Add(element.ToXElement());
            return new ObjectProjectionCriteria(root.ToString(), typeProjection, SCSMServer.CurrentManagementGroup);
        }

        public ObjectProjectionCriteria CreateSimpleCriteria(ManagementPackTypeProjection typeProjection, string property, string value)
        {
            var root = GetRoot();

            var simpleExpression = new SimpleExpression(NameSpace, property, value, ExpressionOperator.Equal);
            root.Add(simpleExpression.ToXElement());
            return new ObjectProjectionCriteria(root.ToString(), typeProjection, SCSMServer.CurrentManagementGroup);
        }

        private XElement GetRoot()
        {
            if (this.managagementpacks.Count == 0)
                throw new InvalidOperationException("At least one reference must be added");

            var root = new XElement(NameSpace + "Criteria");
            for (var i = 0; i < managagementpacks.Count; i++)
            {
                var referenceElement = GetReferenceElement(managagementpacks[i], aliases[i]);
                root.Add(referenceElement);
            }
            return root;
        }

    }
}
